package com.ys.service.overseas.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.config.MenuId;
import com.ys.dto.AddDto;
import com.ys.entity.flow.YspModel;
import com.ys.entity.overseas.*;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsCol;
import com.ys.entity.sys.YsMenu;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.overseas.TosPurchasePlanSonEnum;
import com.ys.mapper.overseas.*;
import com.ys.service.flow.YspTaskService;
import com.ys.service.overseas.TosPurchasePlanService;
import com.ys.util.CheckUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * @Author: fxz
 * @CreateTime: 2024-12-18
 * @Description: HW采购计划
 * @Version: 1.5
 */
@Service("tosPurchasePlanService")
public class TosPurchasePlanServiceImpl implements TosPurchasePlanService {

    @Autowired
    private CheckUtil checkUtil;

    @Autowired
    private TosPurchasePlanMapper tosPurchasePlanMapper;

    @Autowired
    private TosPurchasePlanSonMapper tosPurchasePlanSonMapper;

    @Autowired
    private YspTaskService yspTaskService;

    @Autowired
    private OverseasMapper overseasMapper;

    @Autowired
    private TosPurchasePlanItemMapper tosPurchasePlanItemMapper;

    @Autowired
    private TosChannelStockMapper tosChannelStockMapper;


    /**
     * 新增
     * @param params
     * @param subData
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R add(Map<String, Object> params, String subData) throws Exception {
        //验证
        String msg = yzMsg(params);
        if (msg != null){
            return R.error(msg);
        }
        TosPurchasePlan tosPurchasePlan = JSON.parseObject(JSON.toJSONString(params), TosPurchasePlan.class);
        if (new TosPurchasePlan().setBid(tosPurchasePlan.getBid()).count() != 0){
            return R.error("该单号已存在，核实后再操作!");
        }
        // 验证是否有详情数据
        JSONArray detailJA = JSON.parseArray(subData);
        if (detailJA == null || detailJA.size() == 0) {
            return R.error("详情数据不能为空");
        }
        for (int i = 0; i < detailJA.size(); i++) {
            JSONObject detailJO = detailJA.getJSONObject(i);
            TosPurchasePlanSon tosPurchasePlanSon = JSON.parseObject(JSON.toJSONString(detailJO), TosPurchasePlanSon.class);
            if (tosPurchasePlanSon.getStockNum() == null || tosPurchasePlanSon.getStockNum() == 0){
                return R.error("购买数量不能为空!");
            }
            if (tosPurchasePlanSon.getOrderCode() == null || tosPurchasePlanSon.getOrderCode().equals("")){
                return R.error("订单号不能为空!");
            }
            if (tosPurchasePlanSon.getStockNum() > tosPurchasePlanSon.getPurchaseNum()){
                return R.error("购买数量不允许大于商品库存!");
            }
            if (tosPurchasePlanSon.getConsignee() == null || tosPurchasePlanSon.getAddressLine() == null ||
                    tosPurchasePlanSon.getCity() == null || tosPurchasePlanSon.getPostalCode() == null
            ||tosPurchasePlanSon.getPhone()== null
            || tosPurchasePlanSon.getConsignee().trim() .equals("")|| tosPurchasePlanSon.getAddressLine().trim() .equals("") ||
                    tosPurchasePlanSon.getCity().trim() .equals("") || tosPurchasePlanSon.getPostalCode().trim() .equals("")
                    ||tosPurchasePlanSon.getPhone().trim() .equals("")
            ){
                return R.error("收货信息不能为空!");
            }
        }
        String loginUserId = ShiroUtils.getUserId();
        TsUserChange tsUserChange = new TsUserChange().setUserId(loginUserId).setStatus(1).queryFirst();

        tosPurchasePlan.setStatus(1);
        tosPurchasePlan.setCreateChangeId(tsUserChange.getId());
        tosPurchasePlan.setEffectStock(FlowEnum.EffectStock.NOT_EFFECT.value);

        Integer purchaseTotal = 0;
        BigDecimal purchaseTotalPrice = BigDecimal.ZERO;
        for (int i = 0; i < detailJA.size(); i++) {
            JSONObject detailJO = detailJA.getJSONObject(i);
            TosPurchasePlanSon tosPurchasePlanSon = JSON.parseObject(JSON.toJSONString(detailJO), TosPurchasePlanSon.class);
            tosPurchasePlanSon.setPbid(tosPurchasePlan.getBid());
            purchaseTotal = purchaseTotal + tosPurchasePlanSon.getStockNum();
            purchaseTotalPrice = purchaseTotalPrice.add((tosPurchasePlanSon.getPurchaseAmount().multiply(new BigDecimal(tosPurchasePlanSon.getStockNum()))));
            tosPurchasePlanSon.setStatus(TosPurchasePlanSonEnum.STATUS.EMPTY.value);
            tosPurchasePlanSonMapper.insert(tosPurchasePlanSon);

        }
        tosPurchasePlan.setPurchaseTotal(purchaseTotal);
        tosPurchasePlan.setPurchaseTotalPrice(purchaseTotalPrice.setScale(2, BigDecimal.ROUND_HALF_UP));
        tosPurchasePlanMapper.insert(tosPurchasePlan);

        YsMenu ysMenu = new YsMenu().setId(MenuId.TOS_PurchasePlan).queryFirst();
        if (ysMenu.getFlowModelId().longValue() != 0L) {
            YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
            String codeModel = yspModel.getCode();
            String createUserId = ShiroUtils.getUserId();
            yspTaskService.init(codeModel, tosPurchasePlan.getBid(), createUserId);
        }

        return R.ok(AddDto.gotoEdit("/web/overseas/tosPurchasePlan/toEdit?bid=" + tosPurchasePlan.getBid()));
    }


    /**
     * 修改
     * @param params
     * @param subData
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R edit(Map<String, Object> params, String subData) throws Exception {
        //验证
        String msg = yzMsg(params);
        if (msg != null){
            return R.error(msg);
        }
        TosPurchasePlan tosPurchasePlan = JSON.parseObject(JSON.toJSONString(params), TosPurchasePlan.class);
        if (new TosPurchasePlan().setBid(tosPurchasePlan.getBid()).where("A.id != " + tosPurchasePlan.getId()).count() != 0){
            return R.error("该单号已存在，核实后再操作!");
        }
        // 验证是否有详情数据
        JSONArray detailJA = JSON.parseArray(subData);
        if (detailJA == null || detailJA.size() == 0) {
            return R.error("详情数据不能为空");
        }
        for (int i = 0; i < detailJA.size(); i++) {
            JSONObject detailJO = detailJA.getJSONObject(i);
            TosPurchasePlanSon tosPurchasePlanSon = JSON.parseObject(JSON.toJSONString(detailJO), TosPurchasePlanSon.class);
            if (tosPurchasePlanSon.getStockNum() == null || tosPurchasePlanSon.getStockNum() == 0){
                return R.error("购买数量不能为空!");
            }
            if (tosPurchasePlanSon.getOrderCode() == null || tosPurchasePlanSon.getOrderCode().equals("")){
                return R.error("订单号不能为空!");
            }
            if (tosPurchasePlanSon.getStockNum() > tosPurchasePlanSon.getPurchaseNum()){
                return R.error("购买数量不允许大于商品库存!");
            }
            if (tosPurchasePlanSon.getConsignee() == null || tosPurchasePlanSon.getAddressLine() == null ||
                    tosPurchasePlanSon.getCity() == null || tosPurchasePlanSon.getPostalCode() == null
                    ||tosPurchasePlanSon.getPhone()== null
                    || tosPurchasePlanSon.getConsignee().trim() .equals("")|| tosPurchasePlanSon.getAddressLine().trim() .equals("") ||
                    tosPurchasePlanSon.getCity().trim() .equals("") || tosPurchasePlanSon.getPostalCode().trim() .equals("")
                    ||tosPurchasePlanSon.getPhone().trim() .equals("")
            ){
                return R.error("收货信息不能为空!");
            }
        }
        List<TosPurchasePlanSon> tosPurchasePlanSonList = new TosPurchasePlanSon().setPbid(tosPurchasePlan.getBid()).queryList();
        for (TosPurchasePlanSon tosPurchasePlanSon : tosPurchasePlanSonList){
        }
        overseasMapper.deleteTosPurchasePlanSonPbid(tosPurchasePlan.getBid());

        Integer purchaseTotal = 0;
        BigDecimal purchaseTotalPrice = BigDecimal.ZERO;
        for (int i = 0; i < detailJA.size(); i++) {
            JSONObject detailJO = detailJA.getJSONObject(i);
            TosPurchasePlanSon tosPurchasePlanSon = JSON.parseObject(JSON.toJSONString(detailJO), TosPurchasePlanSon.class);
            tosPurchasePlanSon.setPbid(tosPurchasePlan.getBid());
            purchaseTotal = purchaseTotal + tosPurchasePlanSon.getStockNum();
            purchaseTotalPrice = purchaseTotalPrice.add((tosPurchasePlanSon.getPurchaseAmount().multiply(new BigDecimal(tosPurchasePlanSon.getStockNum()))));
            tosPurchasePlanSon.setStatus(TosPurchasePlanSonEnum.STATUS.EMPTY.value);
            tosPurchasePlanSonMapper.insert(tosPurchasePlanSon);

        }
        tosPurchasePlan.setPurchaseTotal(purchaseTotal);
        tosPurchasePlan.setPurchaseTotalPrice(purchaseTotalPrice.setScale(2, BigDecimal.ROUND_HALF_UP));
        tosPurchasePlanMapper.update(tosPurchasePlan);

        return R.ok(AddDto.gotoEdit("/web/overseas/tosPurchasePlan/toEdit?bid=" + tosPurchasePlan.getBid()));
    }


    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R flowPass(Long id, String loginUserId) throws Exception {
        TosPurchasePlan tosPurchasePlan = new TosPurchasePlan().setId(id).queryFirst();
        if (tosPurchasePlan == null){
            throw new RuntimeException("HW采购计划单据不存在,请核实后再操作!");
        }
        String bid = tosPurchasePlan.getBid();
        try {
            Flow f = yspTaskService.flowPass(bid, loginUserId);
            if (f.getCode() == Flow.Code.FAILED.value) {
                return R.error(f.getMsg());
            } else {
                if (f.getState() == Flow.State.FINISH.value) {
                    tosPurchasePlan.setEffectStock(1);
                    tosPurchasePlanMapper.update(tosPurchasePlan);
                }
                return R.ok();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R flowRefuse(Long id, String reason, String loginUserId) throws Exception {
        TosPurchasePlan tosPurchasePlan = new TosPurchasePlan().setId(id).queryFirst();
        if (tosPurchasePlan == null){
            throw new RuntimeException("HW采购计划单据不存在,请核实后再操作!");
        }
        String bid = tosPurchasePlan.getBid();
        try {
            R r = yspTaskService.flowRefuse(bid, reason, loginUserId);
            return r;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("HW采购计划退回失败!");
        }
    }

    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R flowInit(Long id, String reason, String loginUserId) throws Exception {
        TosPurchasePlan tosPurchasePlan = new TosPurchasePlan().setId(id).queryFirst();
        if (tosPurchasePlan == null){
            throw new RuntimeException("HW采购计划单据不存在,请核实后再操作!");
        }
        String bid = tosPurchasePlan.getBid();
        try {
            R r = yspTaskService.flowInit(bid, reason, loginUserId);
            return r;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("HW采购计划驳回失败!");
        }
    }

    /**
     * 删除
     * @param id
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R del(Long id) throws Exception {
        TosPurchasePlan tosPurchasePlan = new TosPurchasePlan().setId(id).queryFirst();
        if (tosPurchasePlan == null){
            throw new RuntimeException("HW采购计划单据不存在,请核实后再操作!");
        }

        //判断是否实在制单中
        Integer flowState = yspTaskService.flowState(tosPurchasePlan.getBid());

        if (flowState != 0){
            throw new RuntimeException("HW采购计划单不是制单中,不允许删除!");
        }
        yspTaskService.flowDelete(tosPurchasePlan.getBid(), String.valueOf(tosPurchasePlan.getCreateChangeId()));

        tosPurchasePlanMapper.deleteTrue(id);

        overseasMapper.deleteTosPurchasePlanSonPbid(tosPurchasePlan.getBid());
        return R.ok("删除成功!");
    }


    /**
     * 计划取消
     * @param id
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R qx(Long id) throws Exception {
        TosPurchasePlanSon tosPurchasePlanSon = new TosPurchasePlanSon().setId(id).queryFirst();
        if (tosPurchasePlanSon == null){
            throw new RuntimeException("HW采购计划单据不存在,请核实后再操作!");
        }
        if (tosPurchasePlanSon.getStatus() != 1){
            throw new RuntimeException("HW采购计划单据只允许状态为空计划取消,请核实后再操作!");
        }

        TosPurchasePlan tosPurchasePlan = new TosPurchasePlan().setBid(tosPurchasePlanSon.getPbid()).queryFirst();
        if (tosPurchasePlan == null){
            throw new RuntimeException("HW采购计划单据不存在,请核实后再操作!");
        }
        //判断是否实在制单中
        Integer flowState = yspTaskService.flowState(tosPurchasePlan.getBid());

        if (flowState != 2){
            throw new RuntimeException("HW采购计划单还未审批结束,不允许计划取消!");
        }

        tosPurchasePlanSon.setStatus(TosPurchasePlanSonEnum.STATUS.CANCEL.value);
        tosPurchasePlanSonMapper.update(tosPurchasePlanSon);

        return R.ok("计划取消成功!");
    }

    /**
     * 计划审核
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R sh(Map<String, Object> params) throws Exception {
        if (params.get("list") == null){
            return R.error("请选择数据!");
        }
        String[] strs = params.get("list").toString().split(",");
        for(int i=0,len=strs.length;i<len;i++){
            TosPurchasePlanSon tosPurchasePlanSon = new TosPurchasePlanSon().setId(Long.valueOf(strs[i])).queryFirst();
            if (tosPurchasePlanSon == null){
                throw new RuntimeException("HW采购计划单据不存在,请核实后再操作!");
            }
            if (tosPurchasePlanSon.getStatus() != 1){
                throw new RuntimeException("HW采购计划单据只允许状态为空计划取消,请核实后再操作!");
            }

            TosPurchasePlan tosPurchasePlan = new TosPurchasePlan().setBid(tosPurchasePlanSon.getPbid()).queryFirst();
            if (tosPurchasePlan == null){
                throw new RuntimeException("HW采购计划单据不存在,请核实后再操作!");
            }
            //判断是否实在制单中
            Integer flowState = yspTaskService.flowState(tosPurchasePlan.getBid());

            if (flowState != 2){
                throw new RuntimeException("HW采购计划单还未审批结束,不允许计划审核!");
            }


            if (tosPurchasePlanSon.getStatus() != 1){
                throw new RuntimeException("HW采购计划单据只允许状态为空计划取消,请核实后再操作!");
            }
            tosPurchasePlanSon.setStatus(TosPurchasePlanSonEnum.STATUS.PENDINGPAYMENT.value);

            TosChannelStock tosChannelStock = new TosChannelStock().setProductCode(tosPurchasePlanSon.getCode()).queryFirst();
            TosPlatformInformation tosPlatformInformation = new TosPlatformInformation().setId(tosPurchasePlanSon.getPlatformId()).queryFirst();
            TosProductBasis tosProductBasis = new TosProductBasis().setCode(tosPurchasePlanSon.getCode()).queryFirst();
            TosPurchasePlanItem tosPurchasePlanItem = new TosPurchasePlanItem();
            tosPurchasePlanItem.setPurchasePlanSonId(tosPurchasePlanSon.getId());
            tosPurchasePlanItem.setPbid(tosPurchasePlan.getBid());
            tosPurchasePlanItem.setHwChannel(tosPlatformInformation.getHwChannel());
            tosPurchasePlanItem.setSignCode(tosProductBasis.getSignCode());
            tosPurchasePlanItem.setPurchaseCostPrice(tosChannelStock.getPurchaseCostAmount());
            tosPurchasePlanItem.setDeliveryCostPrice(tosChannelStock.getDeliveryCostAmount());
            tosPurchasePlanItem.setStatus(TosPurchasePlanSonEnum.STATUS.PENDINGPAYMENT.value);
            tosPurchasePlanItemMapper.insert(tosPurchasePlanItem);

            tosPurchasePlanSonMapper.update(tosPurchasePlanSon);
        }

        return R.ok("计划审核成功!");
    }

    private String yzMsg(Map<String, Object> infoMap){
        //验证导入字段
        String backMsg = "";
        //获取pc字段数据
        List<YsCol> listField = new YsCol()
                .where("A.MenuId = "+ MenuId.TOS_PurchasePlan)
                .setOrderby("A.SortNo ASC")
                .queryList();
        //验证必填字段的非空；其他字段的长度限制、类型
        try {
            backMsg = checkUtil.checkTableColLengthAndDataType(
                    "TOS_PurchasePlan",
                    listField,
                    infoMap,
                    ysColItem->ysColItem.getFormEditRequired()!=null && ysColItem.getFormEditRequired() == 1
            );
            if(backMsg!=null && !"".equals(backMsg)){//若有误，则跳过这条信息
                return backMsg;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
